package com.honey.sql92script.parser;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

import jsqlparser.statement.create.table.ColDataType;
import jsqlparser.statement.create.table.ColumnDefinition;
import jsqlparser.statement.create.table.Index;

import com.honey.core.dbmapping.structure.Column;
import com.honey.core.types.FullyQualifiedJavaType;
import com.honey.core.types.JavaTypeResolver;
import com.honey.core.types.JdbcTypeNameTranslator;
import com.honey.core.types.Vendor;
import com.honey.core.utils.EmptyUtility;
import com.honey.core.utils.StringUtility;
import com.honey.sql92script.schema.SqlScriptTableColumn;

/**
 * 解析SQL 92标准的建表语句和建视图语句,建立存储过程语句在SQL99中. 解析模型如下:<br />
 * 	create [operation] schema name( <br />
 *   .....<br /> 
 *  ); <br />
 *  schema包含: TABLE VIEW PROCEDURE<br /> 
 *  name : 名称(表名称 视图名称 存储过程名称 )
 * 
 * @author Administrator
 *
 */
public class Sql92VendorParser extends AbstractScriptParser {
	
	/** default 关键字 */
	private static final String KEYWORD_DEFAULT="DEFAULT";
	
	/** comment 关键字 */
	private static final String KEYWORD_COMMENT="COMMENT";
	
	/** not 关键字 */
	private static final String KEYWORD_NOT="NOT";
	
	/** null 关键字 */
	private static final String KEYWORD_NULL="NULL";
	
	/** primary 关键字 */
	private static final String KEYWORD_PRIMARY="PRIMARY";
	
	/** key 关键字 */
	private static final String KEYWORD_KEY="KEY";
	
	/** ' 关键字  */
	private static final char KEYWORD_QUOTE= '\'';
	
	@Override
	String preprocessor(String script){
		//去掉sql语句中注释,sql语句注释格式:
		// 单行注释:-- 
		// 单行注释://
		// 多行注释:/**/
		StringBuilder sb = new StringBuilder();
		ByteArrayInputStream stream = null;
		BufferedReader reader  = null;
		try{
			stream = new ByteArrayInputStream(script.getBytes());
			reader = new BufferedReader (new InputStreamReader(stream));
			String line= null;
			int startComment =-1;
			int comment=0;
			while((line=reader.readLine())!=null){
				int  comment0 = line.indexOf("/*");
				if(comment0>=0 ){
					comment ++;
				}
				int endComment = line.indexOf("*/");
				if(endComment>=0 ){
					comment --;
					endComment += 2;					
				}
				int comment1= line.indexOf("--");
				int comment2= line.indexOf("//");
				
				if(comment1<comment2 && comment1>=0 && comment2>=0 ){
					startComment =comment1;
				}else if(comment1>comment2 && comment1>=0 && comment2>=0 ){
					startComment =comment2;
				}else if(comment1>=0 || comment2>=0 )  {
					if(comment1>=0 ) startComment=comment1;
					if(comment2>=0 ) startComment=comment2;
				}
				if( comment0 >= 0 ){
					if( startComment ==-1){
						startComment = comment0;
					}else{
						startComment = comment0<startComment?comment0:startComment;
					}
				}
				if(startComment==-1 && endComment >0 ){
					sb.append(line.substring(endComment)).append("\n");
				}else if(startComment < 0 ){
					sb.append(line).append("\n");
				}else if(startComment > 0 ){
					sb.append(line.substring(0, startComment)).append("\n");
					if(endComment < line.length() && comment == 0 &&endComment > -1 ){
						sb.deleteCharAt(sb.length() - 1);
						sb.append(line.substring(endComment)).append("\n");
					}
				}
				startComment =-1;
			}
		}catch(Exception e){
			
		}finally{
			if(reader != null){
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(stream != null){
				try {
					stream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return sb.toString();
	}
	
	@Override
	int endMark(int matchStart,int matchEnd , String script){
		return script.indexOf( ';' , matchEnd ) ;
	}
	
	@Override
	Column createNewTableColumn(ColumnDefinition columnDefinition) {
		SqlScriptTableColumn answer= new SqlScriptTableColumn();
		
		//列名称
		answer.setName( columnDefinition.getColumnName() ); 
		if( !StringUtility.stringHasValue(answer.getName()) ){
			return null;
		}
		
		//列的数据类型
		ColDataType colDataType = columnDefinition.getColDataType();
		if( colDataType != null ){
			//数据类型名称
			answer.setDbTypeName( colDataType.getDataType() ) ;
			//转换成jdbc类型
			answer.setJdbcType(JdbcTypeNameTranslator.getJdbcType( answer.getDbTypeName() ));
			//转换成java对象类型
			JavaTypeResolver javaTypeResolver = new JavaTypeResolver(false);
	        FullyQualifiedJavaType fullyQualifiedJavaType = javaTypeResolver.calculateJavaType(answer);
			if (fullyQualifiedJavaType != null) {
				answer.setFullyQualifiedJavaType(fullyQualifiedJavaType);
	        }else{
	        	return null;
	        }

			//数据类型长度
			List list =  colDataType.getArgumentsStringList() ;
			if(!EmptyUtility.isListEmpty(list) ){
				int size = list.size();
				//整数位长度
				if(size>0){
					String s = list.get(0).toString();
					answer.setLength(Long.parseLong(s));
				}
				//小数位长度
				if(size>1){
					String s = list.get(1).toString();
					answer.setScale(Integer.parseInt(s));
				}
			}
		}
		
		answer.setNullable(true);
		//解析其它项
		List list = columnDefinition.getColumnSpecStrings();
		if(!EmptyUtility.isListEmpty(list) ){
			String word= null;
			boolean isdefault=false,isComment=false,isNotNull=false,isPrimaryKey=false ;
			for(int i =0,size=list.size();i<size;){
				word = list.get(i).toString();
				//解析default值
				if(!isdefault && KEYWORD_DEFAULT.equalsIgnoreCase(word) ){
					if(i + 1<size ){
						word = list.get(++i).toString();
						char c[] = word.toCharArray();
						if(KEYWORD_QUOTE == c[0]&& KEYWORD_QUOTE == c[c.length-1]){
								if(c.length ==2){
									answer.setDefaultValue("");
								}else{
									answer.setDefaultValue(word.substring(1, c.length-1));
								}
								isdefault=true;
						}
					}
				}
				//解析COMMENT值
				else if(!isComment && KEYWORD_COMMENT.equalsIgnoreCase(word) ){
					if(i + 1<size ){
						word = list.get(++i).toString();
						char c[] = word.toCharArray();
						if(KEYWORD_QUOTE == c[0]&& KEYWORD_QUOTE == c[c.length-1]){
								if(c.length ==2)
									answer.setComment("");
								else
									answer.setComment(word.substring(1, c.length-1));
								isComment=true;
						}
					}
				}
				//解析是否为空
				else if(!isNotNull && KEYWORD_NOT.equalsIgnoreCase(word) ){
					if(i + 1<size ){
						word = list.get(++i).toString();
						if(KEYWORD_NULL.equalsIgnoreCase(word) ){
							answer.setNullable(false);
							isNotNull=true;
						}
					}
				}
				//解析主键
				else if( !isPrimaryKey&& KEYWORD_PRIMARY.equalsIgnoreCase(word) ){
					if(i + 1<size ){
						word = list.get(++i).toString();
						if(KEYWORD_KEY.equalsIgnoreCase(word) ){
							answer.setIdentity(true);
							isPrimaryKey=true;
						}
					}
				}
				i++;
			}
		}
		return answer;
	}
	
	@Override
	void setTableConstraint(List<Column> columns,List constraints ){
		if(!EmptyUtility.isListEmpty(constraints) ){
			for(int i =0,size=constraints.size();i<size;){
				Object obj = constraints.get(i);
				if(obj instanceof Index){
					Index index = (Index)obj;
					//index.getColumnsNames()
					if("primary key".equalsIgnoreCase(index.getType()) ){
						List<String> ls = index.getColumnsNames();
						for(String col : ls ){
							for(Column column :columns ){
								if(column.getName().equalsIgnoreCase(col)){
									((SqlScriptTableColumn)column ).setIdentity(true);
								}
							}
						}
					}
				}
			}
		}
	}

	@Override
	Vendor getVendor() {
		return new Vendor("SQL-92",0,0 );
	}
}
